﻿using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Data.SqlClient;
using Newtonsoft.Json;
using System.Web.Script.Serialization;
using System.Collections.Generic;
using System.Threading;
using Microsoft.ComplexEventProcessing;
using Microsoft.ComplexEventProcessing.Linq;
using System.Data.Linq;
using System.Linq;

public class TraceHandler : IObserver<Trace>
{
    // DB configuration
    private IPAddress _dbServer;
    private String _dbName;
    private String _username = "ct";
    private String _password = "ct";
    private SqlConnection _criminalTrackerDB;

    //StreamInsight objects
    //private TraceListener _source;
    //private Server _server;
    //private Application _application;
    //private CepStream<Payload> _stream;

    //// Constants
    //private const String STREAMSERVER = "BRETT_WS2012";
    //private const String STREAMAPP = "CriminalTracker";

    public TraceHandler(TraceListener listener, String dbServer, String dbName)
    {
        _dbServer = IPAddress.Parse(dbServer);
        _dbName = dbName;
        _criminalTrackerDB = new SqlConnection("user id=" + _username + ";" +
                                                "password=" + _password + ";" +
                                                "server=" + _dbServer + ";" +
                                                "Trusted_Connection=yes;" +
                                                "database=" + _dbName + ";" +
                                                "connection timeout=30");

        //using (_source = listener)
        //{
        //    Console.WriteLine("TRACEHANDLER -- connecting to StreamInsight server");
        //    using( _server = Server.Create(STREAMSERVER) )
        //    {
        //        Console.WriteLine("TRACEHANDLER --  creating StreamInsight application");
        //        _application = _server.CreateApplication(STREAMAPP);

        //        Console.WriteLine("TRACEHANDLER --  creating CEP stream from observable (TraceListener)");
        //        _stream = _source.ToPointStream(_application,
        //                                e => PointEvent.CreateInsert(DateTime.Now, new Payload { _trace = e }),
        //                                AdvanceTimeSettings.StrictlyIncreasingStartTime,
        //                                "Observable Stream");
        //    }
        //}
        Reporter reporter = new Reporter();
        new Thread(reporter.report).Start();
    }

    public void Subscribe(IObservable<Trace> observable)
    {
        //Console.WriteLine("TRACEHANDLER -- TraceHandler.Subscribe(listener) called");
        observable.Subscribe(this);
    }

    public void Unsubscribe()
    {

    }

    public void OnCompleted()
    {

    }

    public void OnError(Exception e)
    {
        Console.WriteLine(e.ToString());
    }

    public void OnNext(Trace trace)
    {
        //Console.WriteLine("TRACEHANDLER -- Entering TraceHandler's OnNext");

        //var query = from e in _stream
        //            select new { locationID = myFunctions.restricted(e._trace.lat, e._trace.lon) };
        //foreach (var num in query.ToEnumerable())
        //{
        //    Console.WriteLine("TRACEHANDLER -- >>>>>>>>>>>>>>>>> " + num.ToString());
        //}

        
        _criminalTrackerDB.Open();

        SqlCommand writeToHistory = trace.historyTableInsert();
        writeToHistory.Connection = _criminalTrackerDB;
        writeToHistory.ExecuteNonQuery();
        //Console.WriteLine("TRACEHADNDLER -- wrote incoming Trace to history table");

        // check for restricted zone
        //SqlCommand checkRestricted = trace.restrictedZone();
        //checkRestricted.Connection = _criminalTrackerDB;
        //SqlDataReader myReader = checkRestricted.ExecuteReader();
        Console.WriteLine("TRACEHANDLER -- checking if incoming trace is in a restricted zone");

        //if (myReader.Read())
        //{
        //    Console.WriteLine("**********RESTRICTED ZONE DETECTED***********");
        //    // this trace is in a restricted zone
        //    // write event to event table
        //    // push http post json to UI

        //    // Create a request using a URL that can receive a post
        //    //HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://192.168.1.199:13001");
        //    //request.Method = "POST";
        //    //request.ContentType = "test/json";

        //    //using( var streamWriter = new StreamWriter(request.GetRequestStream()))
        //    //{
        //    //    streamWriter.Write(trace.ToString());
        //    //    Console.WriteLine("TRACEHANDLER -- sent HTTP POST");
        //    //    streamWriter.Flush();
        //    //    streamWriter.Close();
        //    //}

        //    //// get the response
        //    //HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        //    //using (var StreamReader = new StreamReader(response.GetResponseStream()))
        //    //{
        //    //    var result = StreamReader.ReadToEnd();
        //    //    Console.WriteLine("HTTP response = " + result.ToString());
        //    //}
        //}
        //_criminalTrackerDB.Close();
    }

    //public int restricted(double lat, double lon)
    //{
    //    Console.WriteLine("ENTERED RESTRICTED()");
    //    decimal latdec = (decimal)lat;
    //    decimal londec = (decimal)lon;

    //    var db = new criminal_tracker_590.criminaltrackerDBDataContext();

    //    var query = from x in db.locations
    //                where latdec < x.latitude1
    //                && latdec > x.latitude2
    //                && londec > x.longitude1
    //                && londec < x.longitude2
    //                select x.locationID;

    //    Console.WriteLine("OOOOOOOOOOOOOOOOOOOOOOOOO" + query.ToString());




    //    return 0;
    //}
}

//public class myFunctions
//{
//    public static int restricted(double lat, double lon)
//    {
//        Console.WriteLine("MYFUNCTIONS -- ENTERED RESTRICTED()");
//        decimal latdec = (decimal)lat;
//        decimal londec = (decimal)lon;

//        var db = new criminal_tracker_590.criminaltrackerDBDataContext();

//        var query = from x in db.locations
//                    where latdec < x.latitude1
//                    && latdec > x.latitude2
//                    && londec > x.longitude1
//                    && londec < x.longitude2
//                    select x.locationID;

//        Console.WriteLine("MYFUNCTIONS -- OOOOOOOOOOOOOOOOOOOOOOOOO" + query.ToString());
//        return 0;
//    }
//}
